/*****************************************************************************
 *  This file is part of the OpenDomo project.
 *  Copyright(C) 2011 OpenDomo Services SL
 *  
 *  Daniel Lerch Hostalot <dlerch@opendomo.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *****************************************************************************/


// ----------------------------------------------------------------------------
// author: Daniel Lerch <dlerch@gmail.com>, http://opendomo.com
// date: Noviembre 2008
//
// CHANGES:
//
// ----------------------------------------------------------------------------





#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <linux/if_ether.h>
#include <sys/ioctl.h>
#include <conf.h>

// {{{ netconf()
int netconf(const char* iface,char *addr,size_t addrlen,char *bc,size_t bclen) 
{
   struct ifreq if_data;
   int sockd;
   u_int8_t  local_mac[6];
   u_int32_t local_ip;
   u_int32_t local_netmask;
   u_int32_t local_broadcast;
   u_int32_t ip;
   struct in_addr in;

   if (getuid () != 0)
   {
      perror ("You must be root. \n");
      return -1;
   }

   if ((sockd = socket (AF_INET, SOCK_PACKET, htons (ETH_P_ARP))) < 0)
   {
      perror("socket");
      return -1;
   }

   strcpy (if_data.ifr_name, iface);

	/* IP Address */
   if (ioctl (sockd, SIOCGIFADDR, &if_data) < 0) 
   {
      perror ("ioctl(); SIOCGIFADDR \n");
		close(sockd);
      return -1;
   }

   memcpy ((void *) &ip, (void *) &if_data.ifr_addr.sa_data + 2, 4);
   local_ip = ntohl (ip);
   in.s_addr = ip;
	
	strncpy(addr, inet_ntoa(in), addrlen);
	addr[addrlen-1]=0;

	/* Broadcast Address */  
	if (ioctl (sockd, SIOCGIFBRDADDR, &if_data) < 0)  
	{  
		perror ("ioctl(): SIOCGIFBRDADDR \n");  
		close(sockd);
      return -1;
	}  
	memcpy ((void *) &ip, (void *) &if_data.ifr_broadaddr.sa_data + 2, 4);  
	local_broadcast = ntohl (ip);  
   in.s_addr = ip;

	strncpy(bc, inet_ntoa(in), bclen);
	addr[addrlen-1]=0;

	close(sockd);
   return 0;
}
// }}}

int main(int argc, char *argv[])
{
   struct sockaddr_in addr;
   int fd;
   char message[256];
	char ip[16];
	char broadcast[16];

   if(argc!=2)
   {
      printf("Usage: %s <interface>\n\n", argv[0]);
      exit(0);
   }

	if(netconf(argv[1], ip, sizeof(ip), broadcast, sizeof(broadcast))<0)
	{
      perror("netconf");
      exit(0);
	}

   snprintf(message, sizeof(message), "OPENDOMO AGENT %s", ip);


   if((fd=socket(AF_INET, SOCK_DGRAM, 0)) < 0) 
   {
      perror("socket");
      exit(1);
   }

   memset(&addr,0,sizeof(addr));
   addr.sin_family=AF_INET;
   addr.sin_port=htons(PORT);


 	if (inet_aton(broadcast, &addr.sin_addr)==0) 
	{
      perror("inet_ntoa");
      exit(1);
	}

	int bc=1; 
	if(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &bc, sizeof(bc)) == -1) 
	{
		perror("setsockopt (SO_BROADCAST)");
		exit(1);
	}


   while(1) 
   {
		printf("sending: %s\n", message);
      if(sendto(fd, message, strlen(message)+1, 0, 
               (struct sockaddr *) &addr, sizeof(addr)) < 0) 
      {
         perror("sendto");
         exit(1);
      }

      sleep(SEND_INTERVAL);
   }

   return 0;
}


